from time import sleep

"""
--------------------------------------------------------------------
 NOTE: only tested with Prologix GPIB/USB controller!
 This class may be useful in other classes to allow existing code
 to function on a python-Serial type script architecture instead of a
 pyvisa type script architecture
 
 This class to allow drop-in replacement for pyvisa commands using only the
 Serial python package
 
 So far pyvisa's "write", "read", and "ask" have been mimicked (in the crudest fashion)

Revision History:
10 Aug 2010 (LNT)
 - Initial revision

USAGE EXAMPLE
	import visapatch
	import visa
	#...
	class lab_instrument():
		def __init__(self,portNum,portType):
			if portType=='COM':
				self.raw = visapatch.Visapatch_Serial(portNum)
			# NOTE: USB not yet implemented
			#if portType=='USB':
			#	self.raw = visapatch.Visapatch_USB(portNum
			else:
				self.raw = instrument('GPIB::' + str(portNum) + '::INSTR')
		def getData(command):
			return self.raw.ask(command) #now "ask" from pyvisa can be used
--------------------------------------------------------------------
"""

class Visapatch_Serial():
    def __init__(self,portGPIB,serialportref,pmt='\r\n',rmt='\n',auto=False):
        ## Port setup
        self._gpib_ = str(portGPIB)     # set the global GPIB address
        self._pmt_ = pmt                # set the global local termination characters
        self._rmt_ = rmt                # set the global remote termination characters
        self._auto_ = auto              # toggle the Prologix automatic Read after Write feature
        self.ser = serialportref        # pass an instance of a python Serial library object
        self.prologix()
        self.focus()
    
    # Changes Prologix settings so that the needs of the intended instrument are met
    # NOTE: This command must be run before any others!
    def focus(self):
        self.setGPIBaddr()
        self.setPMT()
        if self._auto_: self.autoOn
        else: self.autoOff

    # Prologix Unit-specific setup commands
    def prologix(self):
        self.swrite('++rst')
        self.swrite('++ifc')
        self.swrite('++mode 1')
        self.swrite('++eoi 1')
        self.swrite('++eot_enable 0')
        
    def autoOn(self):
        self.swrite('++auto 0')
    def autoOff(self):
        self.swrite('++auto 1')
    
    def readEnable(self):
        self.swrite('++read eoi')
    
    def setPMT(self):
        pmt = self._pmt_
        if pmt=='\r\n': npmt = '0'
        elif pmt=='\r': npmt = '1'
        elif pmt=='\n': npmt = '2'
        else: npmt = '3'
        self.swrite('++eos '+npmt)
        
    def setGPIBaddr(self):
        self.swrite('++addr '+self._gpib_)
        
    def getGPIBaddr(self):
        self.swrite('++addr')
        return self.sread
        
    def changeGPIBaddr(self,addr):
        self.swrite('++addr '+str(addr))
        
    def ctrl_query(self,command):
        self.swrite(command)
        return self.sread()
    
    def swrite(self,buffer):
        return self.ser.write(buffer+'\n')
    
    def sread(self):
        inChar = self.ser.read()
        inBuff = inChar
        while inChar != self._rmt_:
            inChar = self.ser.read()
            inBuff += inChar
        return inBuff.rstrip('\r'+'\n')
        
################################################################################
## pyvisa-mimicked I/O functions
################################################################################
        
    def write(self,buffer):
        self.focus()
        return self.swrite(buffer)
    
    # this command does not set the GPIB address unless you pass it a True!
    def read(self,notfromAsk=False):
        if notfromAsk:
            self.setGPIBaddr()
        if self._auto_: pass
        else: self.swrite('++read eoi\n')
        return self.sread()
    
    def ask(self,buffer):
        self.write(buffer)
        return self.read()